#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
文件工具模块
提供文件处理相关的辅助函数
"""

import os
import logging
import chardet
from pathlib import Path
from typing import Dict, List, Tuple, Optional, Any

from config.constants import DEFAULT_ENCODINGS, FILE_TYPES


# 初始化日志记录器
logger = logging.getLogger("file_utils")


def detect_encoding(file_path: str, sample_size: int = 10000) -> str:
    """检测文件编码
    
    Args:
        file_path: 文件路径
        sample_size: 采样大小
        
    Returns:
        检测到的编码
    """
    try:
        with open(file_path, 'rb') as f:
            raw_data = f.read(sample_size)
            result = chardet.detect(raw_data)
            encoding = result['encoding']
            confidence = result['confidence']
            
            logger.debug(f"文件 {file_path} 编码检测结果: {encoding} (置信度: {confidence})")
            
            if not encoding or confidence < 0.7:
                logger.warning(f"编码检测置信度低: {confidence}，使用默认UTF-8")
                return DEFAULT_ENCODINGS[0]
                
            return encoding
    except Exception as e:
        logger.error(f"编码检测失败: {str(e)}")
        return DEFAULT_ENCODINGS[0]


def get_file_type(file_path: str) -> Optional[str]:
    """根据文件扩展名判断文件类型
    
    Args:
        file_path: 文件路径
        
    Returns:
        文件类型: 'CSV', 'PARQUET' 或 None
    """
    try:
        file_ext = Path(file_path).suffix.lower()
        
        for file_type, info in FILE_TYPES.items():
            if file_ext in info['extensions']:
                return file_type
                
        return None
    except Exception as e:
        logger.error(f"获取文件类型失败: {str(e)}")
        return None


def is_file_valid(file_path: str) -> bool:
    """检查文件是否有效
    
    Args:
        file_path: 文件路径
        
    Returns:
        是否有效
    """
    if not os.path.exists(file_path):
        logger.warning(f"文件不存在: {file_path}")
        return False
        
    if not os.path.isfile(file_path):
        logger.warning(f"不是文件: {file_path}")
        return False
        
    if os.path.getsize(file_path) == 0:
        logger.warning(f"文件大小为0: {file_path}")
        return False
        
    # 检查是否支持的文件类型
    file_type = get_file_type(file_path)
    if not file_type:
        logger.warning(f"不支持的文件类型: {file_path}")
        return False
        
    return True


def get_file_info(file_path: str) -> Dict[str, Any]:
    """获取文件信息
    
    Args:
        file_path: 文件路径
        
    Returns:
        文件信息字典
    """
    try:
        path = Path(file_path)
        file_type = get_file_type(file_path)
        
        return {
            'name': path.name,
            'path': str(path.absolute()),
            'size': os.path.getsize(file_path),
            'type': file_type,
            'extension': path.suffix,
            'parent': str(path.parent),
            'last_modified': os.path.getmtime(file_path)
        }
    except Exception as e:
        logger.error(f"获取文件信息失败: {str(e)}")
        return {
            'name': Path(file_path).name,
            'path': file_path,
            'error': str(e)
        }
